import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ConfigService } from '@nestjs/config';
import { NestFastifyApplication } from '@nestjs/platform-fastify';
import fastifyApp from './common/adapters/fastify.adapter';
import {  Logger } from '@nestjs/common';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import helmet from 'helmet';
import type { NestConfig, CorsConfig, SwaggerConfig } from './config/config.interface'
import { LoggerService } from './shared/logger/logger.services'

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(AppModule, fastifyApp, {
    bufferLogs: true,
    snapshot: true,
    forceCloseConnections: true,
  },);
  const logger = new Logger("ServicesState");

  // app 关闭钩子
  app.enableShutdownHooks();

  const configService = app.get(ConfigService);

  const corsConfig = configService.get<CorsConfig>("corsConfig");

  const swaggerConfig = configService.get<SwaggerConfig>("swaggerConfig");

  const nestConfig = configService.get<NestConfig>("nestConfig");

  // app 开启跨域
  if (corsConfig?.enabled) {
    app.enableCors({ 
      origin: "*", 
      methods: ["GET", "POST", "PUT", "DELETE", "PATCH"], 
      credentials: false, 
      allowedHeaders: ['Content-Type', 'Authorization', 'Accept', 'X-Requested-With'],
    });
  }

  // 开启安全防护, 取消https强制转换
  app.use(helmet({ contentSecurityPolicy: false }));

  // app 开启 swagger
  if (swaggerConfig?.enabled) {
    const options = new DocumentBuilder()
      .setTitle(swaggerConfig.title)
      .setDescription(swaggerConfig.description)
      .setVersion(swaggerConfig.version)
      .addBearerAuth()
      .build();
    const document = SwaggerModule.createDocument(app, options, {
      ignoreGlobalPrefix: true,
      extraModels: [],
    });
    const logger = new Logger("Swagger");
    logger.log(`Swagger is running on ${swaggerConfig.path}`);
    SwaggerModule.setup(swaggerConfig.path, app, document, {
      swaggerOptions: {
        persistAuthorization: true, // 保持登录状态
      }
    });
  }

  // app 开启静态资源
  app.useStaticAssets({ prefix: '/public', root: `${__dirname}/public` });

  // app 开启模板引擎
  app.setViewEngine({
    engine: { ejs: require('ejs') }, 
    templates: `${__dirname}/views`,
  });

  await app.listen(process.env.PORT || nestConfig?.port || 3000, nestConfig?.host || "0.0.0.0", async () => {
    app.useLogger(app.get(LoggerService));
  });
  logger.log(`Server is running on ${nestConfig?.host || "0.0.0.0"}:${process.env.PORT || nestConfig?.port || 3100}`);
}

bootstrap();
